﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

// 玩家有限状态机类
public class FSM : MonoBehaviour
{
    private IState currentState;        // 当前状态接口
    protected Dictionary<StateType, IState> states = new Dictionary<StateType, IState>();  // 状态字典，存储各种状态

    public Parameter parameter;  // 状态机参数

    public virtual void Awake()
    {
        parameter.rb = GetComponent<Rigidbody2D>();
        parameter.animator = GetComponent<Animator>();
        parameter.sr = GetComponent<SpriteRenderer>();
        parameter.character = GetComponent<Character>();

        // 初始化各个状态，并添加到状态字典中
        states.Add(StateType.Idle, new IdleState(this));
        states.Add(StateType.Move, new MoveState(this));
        states.Add(StateType.Dodge, new DodgeState(this));
        states.Add(StateType.MeleeAttack, new MeleeAttackState(this));
        states.Add(StateType.Hit, new HitState(this));
        states.Add(StateType.Death, new DeathState(this));

        TransitionState(StateType.Idle);    // 初始状态为Idle
    }

    public virtual void OnEnable()
    {
        currentState.OnEnter();
    }

    public virtual void Update()
    {
        //有效防止播放最后一段连击后，再播放一次第一段攻击
        parameter.animator.SetBool("isMeleeAttack", parameter.isMeleeAttack);

        parameter.animatorStateInfo = parameter.animator.GetCurrentAnimatorStateInfo(0);// 获取当前动画状态信息

        currentState.OnUpdate();
    }

    public virtual void FixedUpdate()
    {
        currentState.OnFixedUpdate();
    }

    // 状态转换方法
    public void TransitionState(StateType type)
    {
        if (currentState != null)
            currentState.OnExit();// 先调用退出方法

        currentState = states[type];    // 更新当前状态为指定类型的状态
        currentState.OnEnter();         // 调用新状态的进入方法
    }

    // 切换操作映射
    public void SwitchActionMap(InputActionMap actionMap)
    {
        parameter.inputSystem.Disable(); // 禁用当前的输入映射
        actionMap.Enable(); // 启用新的输入映射
    }

    public void Move()
    {
        // 根据当前状态设置角色速度
        parameter.currentSpeed = parameter.isMeleeAttack ? parameter.attackSpeed : parameter.normalSpeed;
        // 设置角色刚体的速度为移动方向乘以当前速度
        parameter.rb.velocity = parameter.inputDirection * parameter.currentSpeed;

        FlipTo();
    }
    
    // 翻转角色
    public void FlipTo()
    {
        if (parameter.inputDirection.x < 0)
        {
            transform.localScale = new Vector3(-1, 1, 1);
        }
        if (parameter.inputDirection.x > 0)
        {
            transform.localScale = new Vector3(1, 1, 1);
        }
    }

    // 开始闪避技能冷却的协程
    public void DodgeOnCooldown()
    {
        StartCoroutine(nameof(DodgeOnCooldownCoroutine));
    }

    public IEnumerator DodgeOnCooldownCoroutine()
    {
        yield return new WaitForSeconds(parameter.dodgeCooldown);// 等待闪避冷却时间
        parameter.isDodgeOnCooldown = false;// 闪避技能冷却结束，设置为不在冷却状态
    }
}
